package cn.com.libertymutual.sp.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import cn.com.libertymutual.core.base.dto.ResponseBaseDto;
import cn.com.libertymutual.core.redis.util.RedisUtils;
import cn.com.libertymutual.core.util.CommonUtil;
import cn.com.libertymutual.core.util.Constants;
import cn.com.libertymutual.core.util.DateUtil;
import cn.com.libertymutual.core.util.ImgCompress;
import cn.com.libertymutual.core.util.StringUtil;
import cn.com.libertymutual.core.util.UtilTool;
import cn.com.libertymutual.core.util.Zip4jUtil;
import cn.com.libertymutual.core.util.enums.CoreServiceEnum;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.core.web.util.RequestUtils;
import cn.com.libertymutual.sp.dto.ClaimCaseResponseDto;
import cn.com.libertymutual.sp.dto.CommonQueryRequestDTO;
import cn.com.libertymutual.sp.dto.CommonQueryRequestPageDTO;
import cn.com.libertymutual.sp.dto.QueryCommonResponseDto;
import cn.com.libertymutual.sp.dto.TQueryPolicyRequstDto;
import cn.com.libertymutual.sp.dto.TQueryPolicyResponseDto;
import cn.com.libertymutual.sp.dto.TQueryReportResponseDto;
import cn.com.libertymutual.sp.dto.TReportClaimRequestDto;
import cn.com.libertymutual.sp.service.api.CaptchaService;
import cn.com.libertymutual.sp.service.api.ClaimsService;
import cn.com.libertymutual.sp.service.api.SmsService;
import cn.com.libertymutual.sys.bean.SysServiceInfo;

/**
 * 
 * @author wkf
 * @date 2017-10-30
 */
@Service("ClaimsService")
public class ClaimsServiceImpl implements ClaimsService {

	private static final Logger logger = LoggerFactory.getLogger(ClaimsService.class);

	@Resource
	private RedisUtils redis;
	@Resource
	private RestTemplate restTemplate;
	@Resource
	private CaptchaService captchaService;// 图形验证码
	@Resource
	private SmsService smsService;// 短信

	@Override
	public ClaimCaseResponseDto queryClaims(TQueryPolicyRequstDto reqeust, HttpServletRequest requestHttp) {
		// policyNo = "8805021301170000020000";
		// Object id =
		// redis.get(Constants.POLICYS_AUTHEN_ID_CAR+":"+requestHttp.getSession().getId());
		if (!"policyNo".equals(reqeust.getType())) {
			Object id = redis.get(Constants.POLICYS_AUTHEN_ID_CAR + ":" + requestHttp.getSession().getId());
			reqeust.setId(id.toString());
		}
		ClaimCaseResponseDto response = new ClaimCaseResponseDto();
		if (StringUtil.isEmpty(reqeust.getPolicyNo()) && StringUtil.isEmpty(reqeust.getId())) {
			response.setStatus(false);
			response.setResultMessage("保单号或身份证号不能为空！");
			return response;
		}
		// reqeust.setPolicyNo("8131051100170000546000");
		Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
		SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.QUERY_CLAIMS_URL.getUrlKey());
		reqeust.setPartnerAccountCode(sysServiceInfo.getUserName());
		// reqeust.setPartnerAccountCode(sysServiceInfo.getUserName());
		reqeust.setFlowId(sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime());

		HttpEntity<TQueryPolicyRequstDto> requestEntity = new HttpEntity<TQueryPolicyRequstDto>(reqeust,
				RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));

		response = restTemplate.postForObject(sysServiceInfo.getUrl(), requestEntity, ClaimCaseResponseDto.class);
		return response;
	}

	@Override
	public ResponseBaseDto reportClaims(TReportClaimRequestDto claimRequest, MultipartFile[] imgFiles) {
		ResponseBaseDto response = new ResponseBaseDto();
		response.setStatus(false);
		try {
			// 获取保存的数据信息
			Map<String, Object> parameterMap = new HashMap<String, Object>();
			if (StringUtil.isEmpty(claimRequest.getProvince()) || StringUtil.isEmpty(claimRequest.getCity())
					|| StringUtil.isEmpty(claimRequest.getIncidentStreetAddress())) {
				throw new Exception("请补全[地图位置]信息！");
			}
			parameterMap.put("AutoPolNo", claimRequest.getAutoPolNo());// 保单号
			if (StringUtil.isEmpty(claimRequest.getIncidentTime())) {
				throw new Exception("请补全[事故时间]信息！");
			}
			// 理赔类型
			if (!"".equals(claimRequest.getClaimType())) {
				parameterMap.put("ClaimType", claimRequest.getClaimType());// 理赔类型
			} else {
				throw new Exception("请补全[理赔类型]信息！");
			}
			parameterMap.put("Province", claimRequest.getProvince());// 省份
			parameterMap.put("City", claimRequest.getCity());// 城市
			parameterMap.put("IncidentStreetAddress", claimRequest.getIncidentStreetAddress());// 地址
			if (!"".equals(claimRequest.getIncidentNotes())) {
				parameterMap.put("IncidentNotes", claimRequest.getIncidentNotes());// 备注
			}
			// 获取多个文件 并压缩
			File zipFile = findFile(imgFiles, claimRequest.getAutoPolNo(), "马上报案_");
			if (zipFile != null) {
				parameterMap.put("upfile", zipFile);// 压缩文件
			} else {
				response.setStatus(false);
				response.setResultMessage("请上传照片资料！");
				return response;
			}
			parameterMap.put("userName", claimRequest.getUserName());// 联系人
			parameterMap.put("phoneNo", claimRequest.getPhoneNo());// 联系电话号码
			parameterMap.put("IncidentTime", claimRequest.getIncidentTime());
			// parameterMap.put("incidentTime", claimRequest.getIncidentTime());
			parameterMap.put("reportMethod", "02");//
			parameterMap.put("langId", "07");//
			parameterMap.put("OtherDriversHomePhone", "07");//
			parameterMap.put("OtherDriversHomePhone2", "07");//
			parameterMap.put("WitnessesPhoneNo", "07");//
			parameterMap.put("WitnessesPhoneNo2", "07");//
			parameterMap.put("PolicePhoneNo2", "07");//
			parameterMap.put("PoliceReportNo", "07");//
			// 封装数据
			int i = 0;
			Part[] parts = new Part[parameterMap.size()];
			for (java.util.Map.Entry<String, Object> entry : parameterMap.entrySet()) {
				if ("upfile".equals(entry.getKey())) {// 压缩文件
					parts[i] = new FilePart(entry.getKey(), (File) entry.getValue());
				} else {
					StringPart part = new StringPart(entry.getKey(), CommonUtil.doEmpty(entry.getValue()), "UTF-8");
					parts[i] = part;
				}
				i++;
			}
			// 发送信息到 理赔报案接口
			Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
			SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.Report_CLAIMS_URL.getUrlKey());
			PostMethod filePost = new PostMethod(sysServiceInfo.getUrl());
			filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
			HttpClient clients = new HttpClient();

			Date d1 = Calendar.getInstance().getTime();
			int status = clients.executeMethod(filePost);
			Date d2 = Calendar.getInstance().getTime();
			long runTime = d2.getTime() - d1.getTime();
			logger.info("马上报案：发送信息到 理赔报案接口用时：" + (runTime / 1000.0) + "秒");

			BufferedReader rd = new BufferedReader(new InputStreamReader(filePost.getResponseBodyAsStream(), "UTF-8"));
			StringBuffer sb = new StringBuffer();
			String line;
			while ((line = rd.readLine()) != null) {
				sb.append(line);
			}
			rd.close();
			logger.info("===================返回的消息：" + sb.toString() + "=========状态码：" + status);
			if ("200".equals(String.valueOf(status).trim())) {
				// 00000-报案成功，赔案号：CQ01146375
				if ("00000".equals(sb.toString().split("-")[0].trim())) {
					// 清空临时文件夹
					UtilTool.deleteDirectory(zipFile.getParent());
					response.setResultMessage(sb.toString().split("：")[1].trim());
					response.setStatus(true);
					/*
					 * logger.info("email content="+sb.toString()); //报案成功之后发送邮件 author:tracy.liao
					 * date:2015-04-24 内容：赔案CQXXXX已通过微信报案成功，请尽快跟进处理！ String subject = "赔案";
					 * if(sb.toString().split("：").length>1){ subject +=
					 * sb.toString().split("：")[1].trim(); } subject +="已通过微信报案成功，请尽快跟进处理！";
					 * logger.info("email subject="+subject);
					 */
					// sendEmail(subject);
				} else {
					response.setResultMessage(sb.toString());
					response.setStatus(false);
				}
			} else {
				response.setResultMessage("信息发送失败！");
				response.setStatus(false);
			}
		} catch (Exception e) {
			response.setResultMessage("报案失败。" + e.getMessage());
			response.setStatus(false);
			logger.error("马上报案：资料发送过程中异常，原因为：" + e.getMessage());
		}
		return response;
	}

	/**
	 * 获取多个文件，并压缩为一个文件
	 * @param multipartRequest
	 * @param documentNo
	 * @param typeName
	 * @return
	 */
	private File findFile(MultipartFile[] imgFiles, String documentNo, String typeName) {

		if (null == imgFiles || imgFiles.length == 0 || StringUtil.isEmpty(documentNo)) {
			return null;
		}
		String path = System.getProperty("java.io.tmpdir") + File.separator + "claims" + File.separator + documentNo;
		if (!new File(path).exists()) {
			new File(path).mkdir();
		}
		// String newDate = UtilTool.getCurrentSysDate("yyyyMMdd");// 年月日
		MultipartFile file = null;
		for (int i = 0; i < imgFiles.length; ++i) {
			// 获取单个文件
			file = imgFiles[i];
			// 文件为空
			if (file.isEmpty()) {
				continue;
			}
			String fileName = file.getOriginalFilename();// 文件名
			// String prefix = fileName.substring(fileName.lastIndexOf("."));//文件后缀
			String photoType = fileName.split("_")[0];
			try {
				if ("imageFileOne".equals(photoType)) {// 事故环境
					photoType = "accident_environmental";
				} else if ("imageFileTwo".equals(photoType)) {// 本车
					photoType = "this_car";
				} else if ("imageFileThree".equals(photoType)) {// 三者车
					photoType = "other_car";
				} else if ("imageFileFour".equals(photoType)) {// 证件
					photoType = "id_card";
				} else if ("imageFileFive".equals(photoType)) {// 你的损失
					photoType = "your_loss";
				}
				// photoType = new String(photoType.getBytes(),"utf-8");
				// 文件目录：指定目录 + 照片类型
				String tmpPath = path + File.separator + photoType;
				File tmpFile = new File(tmpPath);
				if (!tmpFile.exists()) {
					tmpFile.mkdirs();
				}
				// 缩图
				File newFile = new File(tmpPath + File.separator + fileName);
				logger.info("【资料上传】缩略的图片文件名称全路径为：" + newFile.getPath());
				if (file.getSize() > 1048576) {
					ImgCompress.doImgCompress(file.getInputStream(), newFile.getPath());
					// 删除原始图片
				} else {
					ImgCompress.inputstreamtofile(file.getInputStream(), newFile);
				}
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
		// 压缩文件
		File zipFile = null;
		try {
			/*
			 * for(int i=0;i<1000;i++){ String num = UtilTool.doRandom();//随机数 String
			 * url_one = path+ File.separator + typeName+newDate+"_"+documentNo+".zip";
			 * zipFile = new File(url_one); if(!zipFile.exists() && !zipFile.isFile()){
			 * logger.info("马上报案：照片保存预生成的压缩文件全路径为："+zipFile.getPath()); break; } }
			 */
			// 压缩文件夹
			String url_one = path + File.separator + documentNo + ".zip";
			zipFile = new File(url_one);
			logger.info("马上报案：照片保存预生成的压缩文件全路径为：" + zipFile.getPath());
			String zipPath = Zip4jUtil.zip(path + File.separator);
			File tmpFile = new File(zipPath);
			tmpFile.renameTo(zipFile);
			// 清理临时文件和目录
			// UtilTool.deleteDirectory(path + File.separator);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return zipFile;
	}

	@Override
	public TQueryPolicyResponseDto queryPolicys(TQueryPolicyRequstDto requstDto) {
		Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
		SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.QUERY_POLICY_URL.getUrlKey());
		requstDto.setPartnerAccountCode(sysServiceInfo.getUserName());
		requstDto.setFlowId(sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime());
		HttpEntity<TQueryPolicyRequstDto> requestEntity = new HttpEntity<TQueryPolicyRequstDto>(requstDto,
				RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));
		// sysServiceInfo.setUrl("http://10.132.30.148:8850/queryPolicys.do");
		TQueryPolicyResponseDto response = restTemplate.postForObject(sysServiceInfo.getUrl(), requestEntity, TQueryPolicyResponseDto.class);
		return response;
	}

	@Override
	public TQueryPolicyResponseDto queryProposal(TQueryPolicyRequstDto requstDto) {
		Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
		SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.QUERY_Proposal_URL.getUrlKey());
		CommonQueryRequestPageDTO reqeust = new CommonQueryRequestPageDTO();
		reqeust.setPageSize(requstDto.getPageSize());
		reqeust.setPageNumber(999);
		reqeust.setDocumentNo(requstDto.getId());
		reqeust.setPartnerAccountCode(sysServiceInfo.getUserName());
		reqeust.setFlowId(sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime());
		HttpEntity<CommonQueryRequestPageDTO> requestEntity = new HttpEntity<CommonQueryRequestPageDTO>(reqeust,
				RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));
		// sysServiceInfo.setUrl("http://10.132.30.148:8850/queryProposal.do");
		TQueryPolicyResponseDto response = restTemplate.postForObject(sysServiceInfo.getUrl(), requestEntity, TQueryPolicyResponseDto.class);
		return response;
	}

	@Override
	public QueryCommonResponseDto queryPolicyStatus(TQueryPolicyRequstDto requstDto) {
		Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
		SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.QUERY_POLICYSTATUS_URL.getUrlKey());
		/*
		 * HttpHeaders headers = new HttpHeaders(); headers.add("account-code",
		 * sysServiceInfo.getUserName()); headers.add("request-time", String.valueOf(new
		 * Date().getTime())); headers.add("soa-token",
		 * pwdEncoder.encodePassword(sysServiceInfo.getPassword(), String.valueOf(new
		 * Date().getTime())));
		 */

		CommonQueryRequestDTO reqeust = new CommonQueryRequestDTO();
		reqeust.setDocumentNo(requstDto.getId());
		reqeust.setPartnerAccountCode(sysServiceInfo.getUserName());
		reqeust.setFlowId(sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime());
		HttpEntity<CommonQueryRequestDTO> requestEntity = new HttpEntity<CommonQueryRequestDTO>(reqeust,
				RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));
		// sysServiceInfo.setUrl("http://10.132.30.148:8850/queryPolicys.do");
		QueryCommonResponseDto response = restTemplate.postForObject(sysServiceInfo.getUrl(), requestEntity, QueryCommonResponseDto.class);
		return response;
	}

	/**
	 * underwriteflag;//投保单状态：8等待支付，9等待核保 ，1完成，2核保未通过 ，0投保中
	 */
	@Override
	public QueryCommonResponseDto queryProposalStatus(TQueryPolicyRequstDto requstDto) {
		Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
		SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.QUERY_PROPOSALSTATUS_URL.getUrlKey());

		CommonQueryRequestDTO reqeust = new CommonQueryRequestDTO();
		reqeust.setDocumentNo(requstDto.getId());
		reqeust.setPartnerAccountCode(sysServiceInfo.getUserName());
		reqeust.setFlowId(sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime());
		HttpEntity<CommonQueryRequestDTO> requestEntity = new HttpEntity<CommonQueryRequestDTO>(reqeust,
				RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));
		// sysServiceInfo.setUrl("http://10.132.30.148:8850/queryPolicys.do");
		QueryCommonResponseDto response = restTemplate.postForObject(sysServiceInfo.getUrl(), requestEntity, QueryCommonResponseDto.class);
		return response;
	}

	@Override
	public File uploadPhoto(String reportNo, MultipartFile[] imgFiles) {
		File zipFile = this.findFile(imgFiles, reportNo, "资料上传_");

		return zipFile;
	}

	@Override
	public ServiceResult queryReports(HttpServletRequest request, HttpServletResponse response, ServiceResult sr,
			TQueryPolicyRequstDto policyRequest) {
		sr.setResult("没有报案记录");
		// policyRequest.setId("434213126547653211");//测试账号
		Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
		SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.QUERY_Report_URL.getUrlKey());
		/*
		 * HttpHeaders headers = new HttpHeaders(); headers.add("account-code",
		 * sysServiceInfo.getUserName()); headers.add("request-time", String.valueOf(new
		 * Date().getTime())); headers.add("soa-token",
		 * pwdEncoder.encodePassword(sysServiceInfo.getPassword(), String.valueOf(new
		 * Date().getTime())));
		 */

		CommonQueryRequestDTO reqeust = new CommonQueryRequestDTO();
		reqeust.setDocumentNo(policyRequest.getId());
		reqeust.setPartnerAccountCode(sysServiceInfo.getUserName());
		reqeust.setFlowId(sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime());
		HttpEntity<CommonQueryRequestDTO> requestEntity = new HttpEntity<CommonQueryRequestDTO>(reqeust,
				RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));
		// sysServiceInfo.setUrl("http://10.132.21.14:8850/queryReports.do");
		TQueryReportResponseDto responseDto = restTemplate.postForObject(sysServiceInfo.getUrl(), requestEntity, TQueryReportResponseDto.class);
		if (responseDto.getStatus()!=null && responseDto.getStatus()) {
			sr.setSuccess();
			sr.setResult(responseDto.getReports());
		} else {
			sr.setFail();
			sr.setResult(responseDto.getResultMessage());
		}
		sr.setResCode(responseDto.getFlowId());
		return sr;
	}
}
